#include <boost/algorithm/string/join.hpp>
#include <xscript/xprint.h>
#include <xscript/xscriptexecutor.h>
#include <astree/xabstractsyntaxtreeprint.h>

XAbstractSyntaxTreePrint::XAbstractSyntaxTreePrint(XTokenPtr inputToken):
    XAbstractSyntaxTree(inputToken) {
    setName(L"print");
}

bool XAbstractSyntaxTreePrint::invoke(std::shared_ptr<XVariableTable> table) {
    std::vector<std::wstring> items;

    size_t count = getChildCount();
    for (size_t i = 0; i < count; i++) {
        auto child = getChildAt(i);
        if (!child->invoke(table))
            return false;

        auto item = child->getResult();
        auto value = fromToken(item);
        if (!value) {
            XScriptExecutor::getInstance()->setError(XError::XError_BadTokenError, item->asToken()->getToken()->toString());
            return false;
        }
        items.push_back(value->getItemInfo());
    }

    print(std::wcout, boost::algorithm::join(items, L" "));
    return true;
}

std::shared_ptr<XItem> XAbstractSyntaxTreePrint::fromToken(std::shared_ptr<XItem> from) {
    if (from->asToken()) {
        auto token = from->asToken()->getToken();
        auto table = XScriptExecutor::getInstance()->getVariableTable();
        if (!table->setCurrentModule(token->getModuleName()))
            return nullptr;
        if (!table->setCurrentBlock(token->getBlock()))
            return nullptr;

        auto [item, line] = table->getVariable(token->getString());
        return item;
    }
    return from;
}








